package ar.edu.unlu.sistemas.p2p.business.peer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import ar.edu.unlu.sistemas.p2p.business.util.Logger;
import ar.edu.unlu.sistemas.p2p.business.vo.PeerVO;

public class PeerController {
	
	private static PeerController INSTANCE = new PeerController();
	private HashMap<String,Peer> peers = new HashMap<String,Peer>();
	private Peer localPeer;

	private PeerController() {
	
	}

	public synchronized Peer getLocalPeer() {
		return localPeer;
	}

	public synchronized void setLocalPeer(Peer localPeer) {
		this.localPeer = localPeer;
	}
	
	
	public static PeerController getInstance() {
		return INSTANCE;
	}
	

	private HashMap<String, Peer> getPeers() {
		return peers;
	}

	private void setPeers(HashMap<String, Peer> peers) {
		this.peers = peers;
	}
	
	/**
	 * Agrega un peer a la lista administrada
	 * 
	 * @param peerId
	 * @return
	 */
	public synchronized void addPeer(Peer peer) {
		if (!this.getPeers().containsKey(peer.getId())) {
			Logger.logInfo(this.getClass().getName(),"Agrego al vecino "+peer.toString());
			this.getPeers().put(peer.getId(), peer);
		} else {
			Logger.logInfo(this.getClass().getName(),"Ya se encuentra un vecino con ese id");
		}
	}
	
	/**
	 *  Quita un peer de la lista administrada
	 * 
	 * @param peerId
	 * @return Peer
	 */
	public synchronized Peer removePeer(String peerId) {
		Peer removed = null;
		if (this.getPeers().containsKey(peerId)) {
			removed = this.getPeers().remove(peerId);
			Logger.logInfo(this.getClass().getName(),"Remuevo al vecino "+removed.toString());
		} else {
			Logger.logInfo(this.getClass().getName(),"No se encuentra el vecino con ese id");
		}
		return removed;
	}
	
	/**
	 *  Retorna un peer contenido en la lista administrada
	 * 
	 * @param peerId
	 * @return Peer
	 */
	public synchronized Peer getPeer(String peerId) {
		Peer peer =null;
		if (this.getPeers().containsKey(peerId)) {
			peer = this.getPeers().get(peerId);
		}
		return peer;
	}
	
	/**
	 *  Retorna un peer contenido en la lista administrada
	 * 
	 * @param peerId
	 * @return Peers VOs
	 */
	public synchronized Collection<PeerVO> getAllPeers() {
		Iterator<Peer> it = this.getPeers().values().iterator();
		Peer peer;
		PeerVO peerVO;
		Collection<PeerVO> out = new ArrayList<PeerVO>();
		while (it.hasNext()) {
			peer = it.next();
			peerVO = new PeerVO();
			peerVO.setAddress(peer.getAddress());
			peerVO.setId(peer.getId());
			peerVO.setName(peer.getName());
			out.add(peerVO);
		}
		return out;
	}
	
}
